package com.polelink.testcenter.util;

import com.polelink.testcenter.dto.*;
import com.polelink.testcenter.exception.ExcelParseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.math3.util.Pair;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

// IniWriter.java
@Component
@Slf4j
public class IniWriter {

    private static final String LINE_SEPARATOR = System.lineSeparator();

    public String generateIni(List<EcuInfoDto> ecuInfos,
                              Pair<VehicleInfoDto, List<EcuConfigDto>> ecuConfigs,
                              List<ProjectItemDto> pepsItems) {
        StringBuilder iniContent = new StringBuilder();

        // 1. 车辆全局配置
        appendVehicleVariantSection(iniContent, ecuConfigs.getFirst(), ecuInfos.size(), pepsItems.size());

        // 2. DID配置
        appendDidSection(iniContent, ecuConfigs.getFirst().didConfigs());

        // 3. ECU配置
        appendEcuSections(iniContent, ecuInfos, ecuConfigs.getSecond());

        // 4. 测试项配置
        appendTestItemSections(iniContent, pepsItems);

        return iniContent.toString();
    }

    private void appendVehicleVariantSection(StringBuilder sb, VehicleInfoDto vehicleInfo,
                                             int ecuCount, int itemCount) {
        sb.append(";车型全局配置").append(LINE_SEPARATOR);
        sb.append("[vehicle_variant]").append(LINE_SEPARATOR);
        sb.append("variant_type=c100").append(LINE_SEPARATOR);
        sb.append("item_num=").append(itemCount).append(LINE_SEPARATOR);
        sb.append("ecu_num=").append(ecuCount).append(LINE_SEPARATOR);
        sb.append(LINE_SEPARATOR);
    }

    private void appendDidSection(StringBuilder sb, Map<String, DidConfig> didConfigs) {
        int didIndex = 0;
        sb.append(";Vehicle Config Information").append(LINE_SEPARATOR);
        for (Map.Entry<String, DidConfig> entry : didConfigs.entrySet()) {
            sb.append("did").append(didIndex).append("_description=")
                    .append(entry.getKey()).append(LINE_SEPARATOR);
            sb.append("did").append(didIndex).append("=0x")
                    .append(entry.getValue().didNumber()).append(LINE_SEPARATOR);
            sb.append("did").append(didIndex).append("_data=")
                    .append(entry.getValue().data()).append(LINE_SEPARATOR);
            didIndex++;
        }
        sb.append(LINE_SEPARATOR);
    }

    private void appendEcuSections(StringBuilder sb, List<EcuInfoDto> ecuInfos,
                                   List<EcuConfigDto> ecuConfigs) {
        for (int i = 0; i < ecuInfos.size(); i++) {
            EcuInfoDto ecuInfo = ecuInfos.get(i);
            sb.append(";ECU").append(i).append(LINE_SEPARATOR);

            String ecuIndex = "ecu" + i + "_";
            sb.append(ecuIndex).append("name=").append(ecuInfo.ecu()).append(LINE_SEPARATOR);
            sb.append(ecuIndex).append("fbom=").append(ecuInfo.fbom()).append(LINE_SEPARATOR);
            sb.append(ecuIndex).append("diagnostic_id=").append(ecuInfo.diagnosticRequestAddress()).append(LINE_SEPARATOR);
            //todo security_constant,swdl_selected,swdl_sequence,security_dll_path,network_num Excel文件中没有数据来源
            sb.append(ecuIndex).append("security_constant=").append(LINE_SEPARATOR);
            sb.append(ecuIndex).append("swdl_selected=").append(LINE_SEPARATOR);
            sb.append(ecuIndex).append("swdl_sequence=").append(LINE_SEPARATOR);
            sb.append(ecuIndex).append("security_dll_path=").append(LINE_SEPARATOR);
            sb.append(ecuIndex).append("network_num=").append(LINE_SEPARATOR);
            // 增强DID处理逻辑
            ecuConfigs.stream()
                    // 至少要包含ECU Info sheet页对应的ECU或者FBOM信息
                    .filter(config -> config.ecuName().contains(ecuInfo.ecu()) || config.ecuName().contains(ecuInfo.fbom()))
                    .findFirst()
                    .ifPresent(config -> {
                        int didIndex = 0; // 新增DID索引计数器
                        for (Map.Entry<String, String> entry : config.didValues().entrySet()) {
                            String did = entry.getKey();
                            String value = entry.getValue();

                            // 生成DID编号行
                            sb.append(ecuIndex).append("did").append(didIndex).append("=0x")
                                    .append(did.replace(" ", " ")) // 保留原始空格格式
                                    .append(LINE_SEPARATOR);

                            // 生成DID数据行
                            sb.append(ecuIndex).append("did").append(didIndex).append("_data=")
                                    .append(processDidValue(did, value))
                                    .append(LINE_SEPARATOR);

                            didIndex++;
                        }
                    });

            sb.append(LINE_SEPARATOR);
        }
    }

    private String processDidValue(String did, String value) {
        // 实现特殊DID处理规则
        if (did.equalsIgnoreCase("F187")) {
            return value.length() >= 12 ? value.substring(0, 12) : value;
        } else if (did.equalsIgnoreCase("F189")) {
            if (value.length() < 8) {
                throw new ExcelParseException("F189长度不足8位");
            }
            return value;
        }
        return value;
    }

    private void appendTestItemSections(StringBuilder sb, List<ProjectItemDto> pepsItems) {
        sb.append(";测试项配置").append(LINE_SEPARATOR);
        for (int itemIndex = 0; itemIndex < pepsItems.size(); itemIndex++) {
            ProjectItemDto item = pepsItems.get(itemIndex);
            sb.append("[item").append(itemIndex + 1).append("]").append(LINE_SEPARATOR);
            sb.append("item_workstation=").append(item.workstation()).append(LINE_SEPARATOR);
            sb.append("item_name=").append(item.projectName()).append(LINE_SEPARATOR);

            // 收集所有控制器的有效步骤
            Map<String, List<ItemStepDto>> controllerSteps = new LinkedHashMap<>();
            for (SubProjectItemDto subProject : item.subProjectItemList()) {
                for (ItemStepDto step : subProject.steps()) {
                    for (ItemStepDto.ControllerOperation op : step.operations()) {
                        controllerSteps.computeIfAbsent(op.controllerName(), k -> new LinkedList<>())
                                .add(step);
                    }
                }
            }

            // 生成控制器配置
            int controllerIndex = 0;
            for (Map.Entry<String, List<ItemStepDto>> entry : controllerSteps.entrySet()) {
                String controllerName = entry.getKey();
                List<ItemStepDto> steps = entry.getValue().stream()
                        .filter(step -> !step.operations().isEmpty())
                        .toList();

                if (!steps.isEmpty()) {
                    sb.append(";控制器").append(controllerIndex).append(LINE_SEPARATOR);
                    String prefix = "ecu" + controllerIndex + "_";

                    // 控制器基本信息
                    sb.append(prefix).append("name=").append(controllerName).append(LINE_SEPARATOR);
                    sb.append(prefix).append("step_num=").append(steps.size()).append(LINE_SEPARATOR);

                    // 步骤详细信息
                    for (int stepIndex = 0; stepIndex < steps.size(); stepIndex++) {
                        ItemStepDto step = steps.get(stepIndex);
                        String request = step.operations().get(0).request();
                        String response = step.operations().get(0).response();

                        sb.append(prefix).append("step").append(stepIndex).append("=")
                                .append(step.sequence()).append(LINE_SEPARATOR);
                        sb.append(prefix).append("step").append(stepIndex).append("_request=")
                                .append(request).append(LINE_SEPARATOR);
                        sb.append(prefix).append("step").append(stepIndex).append("_response=")
                                .append(response).append(LINE_SEPARATOR);
                    }
                    controllerIndex++;
                }
            }
            sb.append(LINE_SEPARATOR);
        }
    }

}